<?php

namespace app\api\controller;

use think\Controller;
use think\Db;
use tinywan\JWT;

/**
 * 商品规格管理API
 */
class ProductSpec extends Controller
{
    /**
     * 验证JWT Token
     */
    private function verifyToken()
    {
        $token = $this->request->header('Authorization');
        if (empty($token)) {
            return json(['code' => 0, 'msg' => '缺少Authorization头', 'data' => []]);
        }
        
        try {
            $token = str_replace('Bearer ', '', $token);
            $decoded = JWT::decode($token);
            return true;
        } catch (\Exception $e) {
            return json(['code' => 0, 'msg' => 'Token验证失败', 'data' => []]);
        }
    }

    /**
     * 获取规格列表
     * @ApiMethod (GET)
     * @ApiParams (name="status", type="integer", required=false, description="状态筛选：0禁用，1启用")
     */
    public function getSpecList()
    {
        $verify = $this->verifyToken();
        if ($verify !== true) return $verify;

        try {
            $status = $this->request->get('status', '');
            
            $where = [];
            if ($status !== '') {
                $where['status'] = $status;
            }
            
            $specs = Db::name('product_spec')
                ->where($where)
                ->order('sort asc, id asc')
                ->select();
            
            return json(['code' => 1, 'msg' => '获取成功', 'data' => $specs]);
        } catch (\Exception $e) {
            return json(['code' => 0, 'msg' => '获取失败：' . $e->getMessage(), 'data' => []]);
        }
    }

    /**
     * 获取规格值列表
     * @ApiMethod (GET)
     * @ApiParams (name="spec_id", type="integer", required=true, description="规格ID")
     * @ApiParams (name="status", type="integer", required=false, description="状态筛选：0禁用，1启用")
     */
    public function getSpecValueList()
    {
        $verify = $this->verifyToken();
        if ($verify['code'] !== 1) {
            return json($verify);
        }
        
        $merchantId = $verify['merchant_id'];

        try {
            $specId = $this->request->get('spec_id');
            $status = $this->request->get('status', '');
            
            if (empty($specId)) {
                return json(['code' => 0, 'msg' => '规格ID不能为空', 'data' => []]);
            }
            
            // 根据你的表结构，spec_values字段存储JSON格式的规格值
            $spec = Db::name('product_spec')
                ->where(['id' => $specId, 'merchant_id' => $merchantId])
                ->find();
            if (!$spec) {
                return json(['code' => 0, 'msg' => '规格不存在', 'data' => []]);
            }
            
            $specValues = [];
            if (!empty($spec['spec_values'])) {
                $values = json_decode($spec['spec_values'], true);
                if (is_array($values)) {
                    foreach ($values as $index => $value) {
                        $specValues[] = [
                            'id' => $index + 1,
                            'spec_id' => $specId,
                            'value' => isset($value['value']) ? $value['value'] : $value,
                            'image' => isset($value['image']) ? $value['image'] : '',
                            'image_url' => isset($value['image']) && !empty($value['image']) ? 
                                request()->domain() . $value['image'] : '',
                            'sort' => $index,
                            'status' => 1
                        ];
                    }
                }
            }
            
            return json(['code' => 1, 'msg' => '获取成功', 'data' => $specValues]);
        } catch (\Exception $e) {
            return json(['code' => 0, 'msg' => '获取失败：' . $e->getMessage(), 'data' => []]);
        }
    }

    /**
     * 添加规格
     * @ApiMethod (POST)
     * @ApiParams (name="name", type="string", required=true, description="规格名称")
     * @ApiParams (name="spec_values", type="array", required=true, description="规格值数组，格式：['红色','蓝色','绿色'] 或 [{'value':'红色'},{'value':'蓝色'}]")
     * @ApiParams (name="sort", type="integer", required=false, description="排序")
     */
    public function addSpec()
    {
        $verify = $this->verifyToken();
        if ($verify !== true) return $verify;
        
        $merchantId = $verify['merchant_id'];

        try {
            $data = $this->request->post();
            
            if (empty($data['name'])) {
                return json(['code' => 0, 'msg' => '规格名称不能为空', 'data' => []]);
            }
            
            if (empty($data['spec_values']) || !is_array($data['spec_values'])) {
                return json(['code' => 0, 'msg' => '规格值不能为空', 'data' => []]);
            }
            
            // 检查规格名称是否已存在（同一商家下）
            $exists = Db::name('product_spec')
                ->where(['name' => $data['name'], 'merchant_id' => $merchantId])
                ->find();
            if ($exists) {
                return json(['code' => 0, 'msg' => '规格名称已存在', 'data' => []]);
            }
            
            // 处理规格值数据
            $specValues = [];
            foreach ($data['spec_values'] as $index => $value) {
                if (is_string($value)) {
                    // 简单字符串格式：['红色','蓝色']
                    $specValues[] = [
                        'value' => trim($value),
                        'image' => '',
                        'sort' => $index
                    ];
                } elseif (is_array($value) && isset($value['value'])) {
                    // 对象格式：[{'value':'红色','image':''},{'value':'蓝色'}]
                    $specValues[] = [
                        'value' => trim($value['value']),
                        'image' => isset($value['image']) ? $value['image'] : '',
                        'sort' => isset($value['sort']) ? $value['sort'] : $index
                    ];
                }
            }
            
            if (empty($specValues)) {
                return json(['code' => 0, 'msg' => '规格值格式错误', 'data' => []]);
            }
            
            // 验证规格值不能为空且不能重复
            $valueNames = array_column($specValues, 'value');
            $valueNames = array_filter($valueNames); // 过滤空值
            if (empty($valueNames)) {
                return json(['code' => 0, 'msg' => '规格值不能为空', 'data' => []]);
            }
            
            if (count($valueNames) !== count(array_unique($valueNames))) {
                return json(['code' => 0, 'msg' => '规格值不能重复', 'data' => []]);
            }
            
            // 开启事务
            Db::startTrans();
            
            try {
                // 插入规格
                $specData = [
                    'merchant_id' => $merchantId,
                    'name' => $data['name'],
                    'spec_values' => json_encode($specValues, JSON_UNESCAPED_UNICODE),
                    'sort' => isset($data['sort']) ? $data['sort'] : 0,
                    'status' => 1,
                    'createtime' => time(),
                    'updatetime' => time()
                ];
                
                $specId = Db::name('product_spec')->insertGetId($specData);
                
                // 提交事务
                Db::commit();
                
                // 返回完整的规格信息
                $result = [
                    'id' => $specId,
                    'merchant_id' => $merchantId,
                    'name' => $data['name'],
                    'spec_values' => $specValues,
                    'sort' => $specData['sort'],
                    'status' => 1,
                    'createtime' => $specData['createtime'],
                    'updatetime' => $specData['updatetime']
                ];
                
                return json(['code' => 1, 'msg' => '添加成功', 'data' => $result]);
                
            } catch (\Exception $e) {
                Db::rollback();
                throw $e;
            }
            
        } catch (\Exception $e) {
            return json(['code' => 0, 'msg' => '添加失败：' . $e->getMessage(), 'data' => []]);
        }
    }

    /**
     * 更新规格值
     * @ApiMethod (POST)
     * @ApiParams (name="spec_id", type="integer", required=true, description="规格ID")
     * @ApiParams (name="spec_values", type="array", required=true, description="规格值数组")
     */
    public function updateSpecValues()
    {
        $verify = $this->verifyToken();
        if ($verify !== true) return $verify;

        try {
            $data = $this->request->post();
            
            if (empty($data['spec_id'])) {
                return json(['code' => 0, 'msg' => '规格ID不能为空', 'data' => []]);
            }
            
            if (!isset($data['spec_values']) || !is_array($data['spec_values'])) {
                return json(['code' => 0, 'msg' => '规格值数据格式错误', 'data' => []]);
            }
            
            // 检查规格是否存在
            $spec = Db::name('product_spec')->where('id', $data['spec_id'])->find();
            if (!$spec) {
                return json(['code' => 0, 'msg' => '规格不存在', 'data' => []]);
            }
            
            // 更新规格值
            $updateData = [
                'spec_values' => json_encode($data['spec_values'], JSON_UNESCAPED_UNICODE),
                'updatetime' => time()
            ];
            
            Db::name('product_spec')->where('id', $data['spec_id'])->update($updateData);
            
            return json(['code' => 1, 'msg' => '更新成功', 'data' => []]);
        } catch (\Exception $e) {
            return json(['code' => 0, 'msg' => '更新失败：' . $e->getMessage(), 'data' => []]);
        }
    }

    /**
     * 生成SKU组合
     * @ApiMethod (POST)
     * @ApiParams (name="specs", type="array", required=true, description="规格数组")
     */
    public function generateSkuCombinations()
    {
        $verify = $this->verifyToken();
        if ($verify !== true) return $verify;

        try {
            $data = $this->request->post();
            
            if (empty($data['specs']) || !is_array($data['specs'])) {
                return json(['code' => 0, 'msg' => '规格数据不能为空', 'data' => []]);
            }
            
            $specData = [];
            foreach ($data['specs'] as $spec) {
                if (empty($spec['spec_id']) || empty($spec['selected_values'])) {
                    continue;
                }
                
                // 获取规格信息
                $specInfo = Db::name('product_spec')->where('id', $spec['spec_id'])->find();
                if (!$specInfo) {
                    continue;
                }
                
                // 解析规格值
                $specValues = [];
                if (!empty($specInfo['spec_values'])) {
                    $values = json_decode($specInfo['spec_values'], true);
                    if (is_array($values)) {
                        foreach ($spec['selected_values'] as $valueIndex) {
                            if (isset($values[$valueIndex])) {
                                $specValues[] = [
                                    'index' => $valueIndex,
                                    'value' => isset($values[$valueIndex]['value']) ? 
                                        $values[$valueIndex]['value'] : $values[$valueIndex],
                                    'image' => isset($values[$valueIndex]['image']) ? 
                                        $values[$valueIndex]['image'] : ''
                                ];
                            }
                        }
                    }
                }
                
                if (!empty($specValues)) {
                    $specData[] = [
                        'spec_id' => $spec['spec_id'],
                        'spec_name' => $specInfo['name'],
                        'values' => $specValues
                    ];
                }
            }
            
            if (empty($specData)) {
                return json(['code' => 0, 'msg' => '没有有效的规格数据', 'data' => []]);
            }
            
            // 生成笛卡尔积组合
            $combinations = $this->cartesianProduct($specData);
            
            return json([
                'code' => 1, 
                'msg' => '生成成功', 
                'data' => [
                    'total' => count($combinations),
                    'combinations' => $combinations
                ]
            ]);
        } catch (\Exception $e) {
            return json(['code' => 0, 'msg' => '生成失败：' . $e->getMessage(), 'data' => []]);
        }
    }

    /**
     * 生成笛卡尔积组合
     */
    private function cartesianProduct($specData)
    {
        $combinations = [];
        $this->generateCombinations($specData, 0, [], $combinations);
        return $combinations;
    }

    /**
     * 递归生成组合
     */
    private function generateCombinations($specData, $index, $current, &$combinations)
    {
        if ($index == count($specData)) {
            // 生成SKU名称和规格值ID字符串
            $skuName = [];
            $specValueIds = [];
            $specInfo = [];
            
            foreach ($current as $item) {
                $skuName[] = $item['value'];
                $specValueIds[] = $item['spec_id'] . '_' . $item['index'];
                $specInfo[] = [
                    'spec_id' => $item['spec_id'],
                    'spec_name' => $item['spec_name'],
                    'value_index' => $item['index'],
                    'value' => $item['value'],
                    'image' => $item['image']
                ];
            }
            
            $combinations[] = [
                'sku_name' => implode(' ', $skuName),
                'spec_value_ids' => implode(',', $specValueIds),
                'spec_info' => $specInfo,
                'price' => 0,
                'original_price' => 0,
                'stock' => 0,
                'weight' => 0,
                'sku_code' => '',
                'image' => ''
            ];
            return;
        }
        
        foreach ($specData[$index]['values'] as $value) {
            $current[] = [
                'spec_id' => $specData[$index]['spec_id'],
                'spec_name' => $specData[$index]['spec_name'],
                'index' => $value['index'],
                'value' => $value['value'],
                'image' => $value['image']
            ];
            $this->generateCombinations($specData, $index + 1, $current, $combinations);
            array_pop($current);
        }
    }
}